属性的操作

HTML 元素包括标签名和若干个键值对,这个键值对就称为“属性”(attribute)。

属性本身是一个对象(Attr对象),但是实际上,这个对象极少使用。一般都是通过元素节点对象(HTMlElement对象)来操作属性。本章介绍如何操作这些属性。

Element.attributes属性

元素对象有一个attributes属性,返回一个类似数组的动态对象,成员是该元素标签的所有属性节点对象,属性的实时变化都会反映在这个节点对象上。其他类型的节点对象,虽然也有attributes属性,但返回的都是null,因此可以把这个属性视为元素对象独有的。

单个属性可以通过序号引用,也可以通过属性名引用。


返回的都是属性节点对象,而不是属性值。属性节点对象有name和value属性,对应该属性的属性名和属性值,等同于nodeName属性和nodeValue属性。

元素的标准属性

HTML 元素的标准属性(即在标准中定义的属性),会自动成为元素节点对象的属性。


这些属性都是可写的。这种修改属性的方法,常常用于添加表单的属性。

上面代码为表单添加提交网址和提交方法。

注意,这种用法虽然可以读写属性,但是无法删除属性,delete运算符在这里不会生效。

HTML 元素的属性名是大小写不敏感的,但是 JavaScript 对象的属性名是大小写敏感的。转换规则是,转为 JavaScript 属性名时,一律采用小写。如果属性名包括多个单词,则采用骆驼拼写法,即从第二个单词开始,每个单词的首字母采用大写,比如onClick。

有些 HTML 属性名是 JavaScript 的保留字,转为 JavaScript 属性时,必须改
名。主要是以下两个。

属性操作的标准方法

概述

元素节点提供四个方法,用来操作属性。

  1. 适用性 这四个方法对所有的属性(包括用户自定义的属性)都适用。
  2. 返回值 getAttribute()只返回字符串,不会返回其他类型的值。
  3. 属性名 这些方法只接受属性的标准名称,不用改写保留字,比如for和class都可以直接使用。另外,这些方法对于属性名是大小写不敏感的。

Element.getAttribute()

lement.getAttribute方法返回当前元素节点的指定属性。如果指定属性不存在,则返回null。

Element.setAttribute()

Element.setAttribute方法用于为当前元素节点新增属性。如果同名属性已存在,则相当于编辑已存在的属性。

Element.hasAttribute()

Element.hasAttribute方法返回一个布尔值,表示当前元素节点是否包含指定属性。

Element.removeAttribute()

Element.removeAttribute方法用于从当前元素节点移除属性。

dataset 属性

有时,需要在HTML元素上附加数据,供 JavaScript 脚本使用。一种解决方法是自定义属性。使用标准提供的data-*属性。

然后,使用元素节点对象的dataset属性,它指向一个对象,可以用来操作 HTML 元素标签的data-*属性。

通过dataset.foo读写data-foo属性。删除一个data-*属性,可以直接使用delete命令。

除了dataset属性,也可以用getAttribute(‘data-foo’)、removeAttribute(‘data-foo’)、setAttribute(‘data-foo’)、hasAttribute(‘data-foo’)等方法操作data-*属性。

Text节点和DocumentFragment节点

Text节点的概念

文本节点(Text)代表元素节点(Element)和属性节点(Attribute)的文本内容。如果一个节点只包含一段文本,那么它就有一个文本子节点,代表该节点的文本内容。

通常我们使用父节点的firstChild、nextSibling等属性获取文本节点,或者使用Document节点的createTextNode方法创造一个文本节点。

浏览器原生提供一个Text构造函数。它返回一个文本节点实例。它的参数就是
该文本节点的文本内容。

文本节点继承了Node接口,所以属性和方法都和Node一样。

Text节点的属性

data

data属性等同于nodeValue属性,用来设置或读取文本节点的内容。

wholeText

wholeText属性将当前文本节点与毗邻的文本节点,作为一个整体返回。大多数情况下,wholeText属性的返回值,与data属性和textContent属性相同。

length

length属性返回当前文本节点的文本长度。

nextElementSibling,previousElementSibling

nextElementSibling属性返回紧跟在当前文本节点后面的那个同级元素节点。如果取不到元素节点,则返回null。

previousElementSibling属性返回当前文本节点前面最近的同级元素节点。如果取不到元素节点,则返回null:。

Text节点的方法

appendData(),deleteData(),insertData(),replaceData(),subStringData()

remove()

remove方法用于移除当前Text节点。

splitText()

splitText方法将Text节点一分为二,变成两个毗邻的Text节点。它的参数就是分割位置(从零开始),分割到该位置的字符前结束。如果分割位置不存在,将报错。

分割后,该方法返回分割位置后方的字符串,而原Text节点变成只包含分割位置前方的字符串。


父元素的normalize方法可以实现逆操作,将它们合并。

DocumentFragment节点

DocumentFragment节点代表一个文档的片段,本身就是一个完整的 DOM 树形结构。它没有父节点,parentNode返回null,但是可以插入任意数量的子节点。它不属于当前文档,操作DocumentFragment节点,要比直接操作 DOM 树快得多。

它一般用于构建一个 DOM 结构,然后插入当前文档。document.createDocumentFragment方法,以及浏览器原生的DocumentFragment构造函数,可以创建一个空的DocumentFragment节点。然后再使用其他 DOM 方法,向其添加子节点。


上面代码创建了一个DocumentFragment节点,然后将一个li节点添加在它里面,最后将DocumentFragment节点移动到原文档。

注意,DocumentFragment节点本身不能被插入当前文档。当它作为appendChild()、insertBefore()、replaceChild()等方法的参数时,是它的所有子节点插入当前文档,而不是它自身。一旦DocumentFragment节点被添加进当前文档,它自身就变成了空节点(textContent属性为空字符串),可以被再次使用。如果想要保存DocumentFragment节点的内容,可以使用cloneNode方法。


上面这样添加DocumentFragment节点进入当前文档,不会清空DocumentFragment节点。

DocumentFragment节点对象没有自己的属性和方法,全部继承自Node节点和ParentNode接口。也就是说,DocumentFragment节点比Node节点多出以下四个属性。